package cn.edu.dutir.utility;

import java.util.Comparator;

/**
 * A <code>ScoredObject</code> provides an implementation of the
 * <code>Scored</code> interface with an attached object.  Scored
 * objects are immutable and identity is reference.  The object
 * returned by the getter {@link #getObject()} is the actual object
 * stored, so changes to it will affect the scored object of which it
 * is a part.
 *
 */
public class ScoredObject<E> implements Scored {

	private final double mScore;
	private final E mObject;

	
    /**
     * Construct a scored object from the specified object
     * and score.
     *
     * @param obj Object for the constructed scored object.
     * @param score Score for the constructed scored object.
     */
	public ScoredObject(E object, double score) {
		this.mObject = object;
		this.mScore = score;
	}

    /**
     * Returns the object attached to this scored object.
     *
     * @return The object attached to this scored object.
     */
	public double score() {
		return mScore;
	}

	 /**
     * Returns the score for this scored object.
     *
     * @return The score for this scored object.
     */
	public E getObject() {
		return mObject;
	}

    /**
     * Returns a string-based representation of this object consisting
     * of the score followed by a colon (<code>':'</code>), followed
     * by the object converted to a string.
     *
     * @return The string-based representation of this object.
     */
	public String toString() {
		return mObject + " : " + mScore;
	}

	/**
	 * A comparator used for sorting objects in ascending order. 
	 *
	 */
	static class ScoredComparator implements Comparator<Scored> {

		public int compare(Scored o1, Scored o2) {
			return o1.score() < o2.score() ? -1 : (o1.score() > o2.score() ? 1
					: 0);
		}
	}

	/**
	 * A comparator used for sorting objects in descending order.
	 *
	 */
	static class ReverseScoredComparator implements Comparator<Scored> {

		public int compare(Scored o1, Scored o2) {
			return o1.score() < o2.score() ? 1 : (o1.score() > o2.score() ? -1
					: 0);
		}
	}
}